/*
 * Copyright Andrew V. Pogrebnyak
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.forumj.web.requesthandler.handler;

import static org.forumj.tool.Diletant.*;
import static org.forumj.tool.FJServletTools.*;
import static org.forumj.web.servlet.tool.FJServletTools.*;

import java.io.*;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.*;

import javax.servlet.*;
import javax.servlet.http.*;

import org.apache.commons.configuration.ConfigurationException;
import org.forumj.common.FJUrl;
import org.forumj.common.db.entity.*;
import org.forumj.common.db.service.*;
import org.forumj.common.exception.*;
import org.forumj.common.tool.*;
import org.forumj.common.web.ThreadType;
import org.forumj.tool.LocaleString;
import org.forumj.web.requesthandler.BaseHandler;

import com.tecnick.htmlutils.htmlentities.HTMLEntities;

/**
 * 
 * @author <a href="mailto:an.pogrebnyak@gmail.com">Andrew V. Pogrebnyak</a>
 */
public class ForumThreadHandler extends BaseHandler{

    @Override
    protected void doHandle(AsyncContext context) throws FJWebException {
        try{
            HttpServletRequest request = (HttpServletRequest) context.getRequest();
            HttpServletResponse response = (HttpServletResponse) context.getResponse();
            long startTime = new Date().getTime();
            StringBuffer buffer = new StringBuffer();
            HttpSession session = request.getSession();
            cache(response);
            // Какой это номер страницы? если без номера, то первый
            Integer pageNumber = request.getParameter("page") == null ? 1 : Integer.valueOf(request.getParameter("page"));
            // id Темы
            Long threadId = request.getParameter("id") == null ? 1 : Long.valueOf(request.getParameter("id"));
            // Номер поста, на который отвечаем
            String replyPostParameter = request.getParameter("reply");
            String end = request.getParameter("end");
            // Зашли с поиска?
            String msg = request.getParameter("msg");
            VoiceService voiceService = FJServiceHolder.getVoiceService();
            PostService postService = FJServiceHolder.getPostService();
            SubscribeService subscribeService = FJServiceHolder.getSubscribeService();
            ThreadService treadService = FJServiceHolder.getThreadService();
            IFJThread thread = treadService.readThread(threadId);
            boolean isAnswer = replyPostParameter != null && !"".equals(replyPostParameter.trim());
            LocaleString locale = (LocaleString) session.getAttribute("locale");
            IUser user = (IUser) session.getAttribute("user");
            IgnorService ignorService = FJServiceHolder.getIgnorService();
            List<IIgnor> ignorList = ignorService.readUserIgnor(user.getId());
            // Сколько страниц?
            Integer count = thread.getPcount();
            Integer couP = (int) (Math.floor((double)count/user.getPt())+2);
            // Если цитирование или последний пост, то нам на последнюю
            boolean lastPost = false;
            if (isAnswer || end != null){
               pageNumber = couP-1;
               lastPost = true;
            }
            int nfirstpost = (pageNumber-1)*user.getPt();
            List<IFJPost> posts = postService.readPosts(user, threadId, nfirstpost, user.getPt(), pageNumber, lastPost);
            int postsAmount = posts.size();
            // Получаем массив постов
            session.setAttribute("page", pageNumber);
            session.setAttribute("id", threadId);
            session.setAttribute("where", request.getContextPath() + "?id=" + threadId + "&page=" + pageNumber);
            int countPosts = 0;
            if (msg != null && !"".equals(msg.trim())){
               try {
                  Long msgId = new Long(msg);
                  countPosts = postService.getPostsCountInThread(threadId, msgId);
               } catch (NumberFormatException e) {
                  e.printStackTrace();
                  msg = null;
               }
               pageNumber=(int) (Math.floor(countPosts/user.getPt()) + 1);
            }
            // Записываем счетчики
            // Робот?
            if (!isRobot(request)){
               // Нет
               treadService.setSeen(user, threadId);
            }
            // Ссылки на другие страницы  Тут надо убрать colspan!
            buffer.append("<div>");
            buffer.append("<table width=100%>");
            buffer.append("<tr>");
            buffer.append("<td>");
            buffer.append("<table>");
            buffer.append("<tr>");
            buffer.append("<td class='page'>");
            buffer.append("<font class=mnuforum><b>" + locale.getString("mess22") + "&nbsp;</b></font>");
            buffer.append("</td>");
            int i2=0;
            for (int i1=1; i1<couP; i1++){
               i2=i2+1;
               if ((i1>(pageNumber-5) && i1<(pageNumber+5))||i2==10||i1==1||i1==(couP-1)){
                  if (i2==10) i2=0;
                  if (i1==pageNumber){
                     buffer.append("<td class='pagecurrent'>");
                     buffer.append("<span class=mnuforum><b>"+i1 + "</b></span>");
                     buffer.append("</td>");
                  }
                  else {
                     buffer.append("<td class='page'>");
                     buffer.append("<a class=mnuforum href='" + FJUrl.VIEW_THREAD + "?page="+i1 + "&id="+threadId + "'>"+i1 + "</a>");
                     buffer.append("</td>");
                  }
               }
            }
            buffer.append("</tr>");
            buffer.append("</table>");

            buffer.append("</td>");

            buffer.append("<td align=right>");
            // Сторінка сформована :)
            buffer.append("<span class=posthead>"+ locale.getString("mess91") + "</span>");
            buffer.append("</td>");
            buffer.append("</tr></table>");
            buffer.append("</td>");
            buffer.append("</tr></table></td></tr>");
            // Таблица главных ссылок кончилась
            //Строка с таблицей форума
            buffer.append("<tr><td height='400' valign='top'>");
            // Таблица форума
            buffer.append("<table border='0' cellpadding='2' cellspacing='0' width='100%'>");
            // Определяем кол-во строк таблицы
            if (postsAmount>count) {
               postsAmount=count-(pageNumber-1)*user.getPt();
            }else{
               postsAmount=user.getPt();
            }
            // Тема
            // Выводим строки
            for (int postIndex = 0; postIndex < posts.size(); postIndex++) {
               IFJPost post = posts.get(postIndex);
               buffer.append(writePost(post, ignorList, user, pageNumber, locale, thread, voiceService));
            }
            // /Таблица форума
            buffer.append("</table>");
            // "Граница" внизу
            buffer.append("</td>");
            buffer.append("</tr>");
            // Таблица главных ссылок
            // Ссылки на страницы
            buffer.append("<tr>");
            buffer.append("<td width='100%'>");
            buffer.append("<table border='0' style='border-collapse: collapse' width='100%'>");
            buffer.append("<tr>");
            buffer.append("<td colspan='5'>");
            buffer.append("<table>");
            buffer.append("<tr>");
            buffer.append("<td class='page'>");
            buffer.append("<font class=mnuforum><b>" + locale.getString("mess22") + "&nbsp;</b></font>");
            buffer.append("</td>");
            i2=0;
            for (int i1=1; i1<couP; i1++){
               i2=i2+1;
               if ((i1>(pageNumber-5) && i1<(pageNumber+5))||i2==10||i1==1||i1==(couP-1)){
                  if (i2==10) i2=0;
                  if (i1==pageNumber){
                     buffer.append("<td class='pagecurrent'>");
                     buffer.append("<span class=mnuforum><b>"+i1 + "</b></span>");
                     buffer.append("</td>");
                  }
                  else {
                     buffer.append("<td class='page'>");
                     buffer.append("<a class=mnuforum href='" + FJUrl.VIEW_THREAD + "?page="+i1 + "&id="+threadId + "'>"+i1 + "</a>");
                     buffer.append("</td>");
                  }
               }
            }
            buffer.append("</tr>");
            buffer.append("</table>");
            buffer.append("</td>");
            buffer.append("</tr>");
            // Главное "меню"
            buffer.append("</table></td></tr>");
            if (user.isLogined() && !user.isBanned() && !thread.isClosed()){
               //Форма подписки/отписки  на ветку
               //Мы уже подписаны?
               String action = "";
               String mess = "";
               if (subscribeService.isUserSubscribed(threadId, user.getId())){
                  //Подписка есть, предлагаем отказаться
                  action = FJUrl.DELETE_SUBSCRIBE + "?pg=" + pageNumber;
                  mess = locale.getString("mess90");
               }else{
                  //Подписки нет - тогда предлагаем подписаться
                  action= FJUrl.ADD_SUBSCRIBE + "?pg="+pageNumber;
                  mess=locale.getString("mess89");   
               }
               buffer.append("<tr>");
               buffer.append("<td align=right>");
               buffer.append("<form id='subs' action='" + action + "' method='post'>");
               buffer.append("<table>");
               buffer.append("<tr>");
               buffer.append("<td>");
               buffer.append(fd_button(mess,"subscribe();","btn_subs", "1"));
               //Прередаем нужные пераметры...
               buffer.append("<input type=hidden name='IDT' value='" + threadId + "'>");
               buffer.append(fd_form_add(user));
               buffer.append("</td>");
               buffer.append("</tr>");
               buffer.append("</table>");
               buffer.append("</form>");
               buffer.append("</td>");
               buffer.append("</tr>");
               String re="";
               String head = thread.getHead();
               IFJPost replyPost = null;
               // Если цитируем/редактируем
               if (isAnswer) {
                  replyPost = postService.read(Long.valueOf(replyPostParameter));
                  head = removeSlashes(replyPost.getHead().getTitle());
               }
               // Новое мнение
               // Форма нового поста
               buffer.append("<tr>");
               buffer.append("<td>");
               buffer.append("<a name='edit'>&nbsp;");
               buffer.append("</a>");
               buffer.append("<table>");
               buffer.append("<tr>");
               buffer.append("<td>");
               buffer.append("<form name='post' action='" + FJUrl.ADD_POST + "' method='post'>");
               buffer.append("<table width='100%'>");
               //Тема
               buffer.append("<tr>");
               buffer.append("<td colspan='2' align='CENTER'>");
               buffer.append("<table>");
               buffer.append("<tr>");
               buffer.append("<td>");
               buffer.append(locale.getString("mess59") + ":&nbsp;");
               buffer.append("</td>");
               buffer.append("<td>");
               buffer.append(fd_input("NHEAD", re + HtmlChars.convertHtmlSymbols(head), "70", "1"));
               buffer.append("</td>");
               buffer.append("</tr>");
               buffer.append("</table>");
               buffer.append("</td>");
               buffer.append("</tr>");
               buffer.append("<tr>");
               //Смайлики заголовок
               buffer.append("<td width='400' align='CENTER'>");
               buffer.append("<p>");
               buffer.append(locale.getString("mess21") + ":");
               buffer.append("</p>");
               buffer.append("</td>");
               //Приглашение
               buffer.append("<td align='CENTER'>");
               buffer.append("<p>");
               buffer.append(locale.getString("mess12"));
               buffer.append("</p>");
               buffer.append("</td>");
               buffer.append("</tr>");
               //Пост
               buffer.append("<tr>");
               buffer.append("<td valign='TOP' width='100%' height='100%'>");
               //Смайлики
               buffer.append(smiles_add(locale.getString("mess11")));
               buffer.append("</td>");
               buffer.append("<td width='500' align='CENTER' valign='top'>");
               //Автотеги
               buffer.append(autotags_add());
               // текстарий
               String textarea="";
               if (isAnswer) {
                  String ans = request.getParameter("ans");
                  if (replyPost.getHead().getAuth().equals(user.getId())){
                     textarea += HtmlChars.convertHtmlSymbols(removeSlashes(replyPost.getBody().getBody()));
                  }else if (ans == null){
                     textarea += "[quote][b]" + HtmlChars.convertHtmlSymbols(removeSlashes(replyPost.getHead().getAuthor().getNick())) + "[/b] ";
                     textarea += locale.getString("mess14")+String.valueOf((char) 13);
                     textarea += HtmlChars.convertHtmlSymbols(removeSlashes(replyPost.getBody().getBody())) + "[/quote]";
                  }else{
                     textarea += "[b]" + removeSlashes(replyPost.getHead().getAuthor().getNick()) + "[/b]";
                     textarea += ", ";
                  }
               }
               buffer.append("<textarea rows='20' class='mnuforumSm' id='ed1' name='A2' cols='55'>" + textarea + "</textarea>");
               buffer.append("<br>");
               buffer.append("<input type='checkbox' name='no_exit' value='1'>");
               buffer.append(locale.getString("mess123"));
               //Кнопки
               buffer.append("<table>");
               buffer.append("<tr>");
               buffer.append("<td>");
               if (isAnswer && (replyPost.getHead().getAuth().equals(user.getId()))){
                  buffer.append(fd_button(locale.getString("mess13"),"post_submit(\"write_edit\");","B1", "1"));
               }else{
                  buffer.append(fd_button(locale.getString("mess13"),"post_submit(\"write_new\");","B1", "1"));
               }
               buffer.append("</td>");
               buffer.append("<td>");
               if (isAnswer && (replyPost.getHead().getAuth().equals(user.getId()))){
                  buffer.append(fd_button(locale.getString("mess63"),"post_submit(\"view_edit\");","B1", "1"));
               }else{
                  buffer.append(fd_button(locale.getString("mess63"),"post_submit(\"view_new\");","B3", "1"));
               }
               buffer.append("</td>");
               buffer.append("</tr>");
               buffer.append("</table>");
               //Если редактируем
               if (isAnswer && (replyPost.getHead().getAuth().equals(user.getId()))){
                  buffer.append("<input type=hidden name='IDB' size='20' value='" + replyPostParameter + "'>");
                  buffer.append("<input type=hidden name='IDTbl' size='20' value='" + replyPost.getTablePost() + "'>");
                  buffer.append("<input type=hidden name='IDPst' size='20' value='" + replyPost.getId().toString() + "'>");
                  buffer.append("<input type=hidden name='IDTblHead' size='20' value='" + replyPost.getTableHead() + "'>");
                  buffer.append("<input type=hidden name='IDHead' size='20' value='" + replyPost.getId().toString() + "'>");
               }
               //id темы
               buffer.append("<input type=hidden name='IDT' size='20' value='" + threadId + "'>");
               if (thread.isQuest()){
                  buffer.append("<input type=hidden name='ISQUEST' size='20' value='true'>");
               }
               buffer.append(fd_form_add(user));
               buffer.append("</td>");
               buffer.append("</tr>");
               buffer.append("</table>");
               buffer.append("</form>");
               buffer.append("</td>");
               buffer.append("</tr>");
               buffer.append("</table>");
               buffer.append("</td>");
               buffer.append("</tr>");
            }
            Double allTime = (double) ((new Date().getTime() - startTime));
            DecimalFormat format = new DecimalFormat("##0.###");
            response.setContentType("text/html; charset=UTF-8");
            PrintWriter writer = response.getWriter();
            String out = buffer.toString();
            writer.write(out.replace("ъъ_ъ", format.format(allTime/1000)));
        }catch (Throwable e){
            throw new FJWebException(e);
        }
    }

    private StringBuffer writePost(IFJPost post, List<IIgnor> ignorList, IUser user, Integer pageNumber, LocaleString locale, IFJThread thread, VoiceService voiceService) throws InvalidKeyException, ConfigurationException, SQLException, IOException{
        StringBuffer buffer = new StringBuffer();
        Time postTime = new Time(post.getHead().getCreateTime());
        IUser author = post.getHead().getAuthor();
        buffer.append("<tr class=heads>");
        buffer.append("<td  class=internal>");
        if (post.isLastPost()) buffer.append("<a name='end'></a>");
        buffer.append("<a name='" + post.getId() + "'>&nbsp;</a>");
        buffer.append("<a class=nik href='" + FJUrl.VIEW_THREAD + "?id=" + post.getThreadId() + "&msg=" + post.getId() + "#" + post.getId() + "'  rel='nofollow'><b>&nbsp;&nbsp;" + fd_head(HTMLEntities.htmlentities(removeSlashes(post.getHead().getTitle()))) + "</b></a>");
        buffer.append("</td></tr>");
        buffer.append("<tr><td>");
        boolean ignored = false;
        String div_ = "";
        if (ignorList.size() > 0){
           if (isIgnored(post.getHead().getAuth(), ignorList)) ignored = true;
        }
        buffer.append("<span class='tbtextnread'>" + HtmlChars.convertHtmlSymbols(author.getNick()) + "</span>&nbsp;•");
        buffer.append("&nbsp;<img border='0' src='smiles/icon_minipost.gif'>&nbsp;<span class='posthead'>" + postTime.toString("dd.MM.yyyy HH:mm") + "</span>&nbsp;");
        if (user.isModerator()){
           buffer.append("•&nbsp;<span class='posthead'>" + post.getHead().getIp() + "</span>&nbsp;" );
        }
        if (!ignored && user.isLogined() && post.getHead().getAuth() != user.getId()){
           buffer.append("•&nbsp;<a class='posthead' href='" + FJUrl.ADD_IGNOR + "?idi=" + post.getHead().getAuth() + "&idt=" + thread.getId() + "&idp=" + post.getId() + "&pg=" + pageNumber + "' rel='nofollow'>" + locale.getString("mess68") + "</a>");
        }
        buffer.append("</td></tr>");
        buffer.append("<tr><td>");
        if (ignored){
           buffer.append("<a href='#' onclick='togglemsg(\"dd" + post.getId() + "\"); return false;' rel='nofollow'>" + locale.getString("mess142") + "</a>");
           div_ =" style='visibility: hidden; display:none;'";
        }else{
           div_ ="";
        }
        buffer.append("<div id=dd" + post.getId().toString() + div_ + ">");
        if ((user.isLogined() || !ignored)){
           buffer.append("<table width='100%'><tr><td valign=top class='matras'>");
           buffer.append("<table style='table-layout:fixed;' width='170'><tr><td valign=top>");
           buffer.append("<div style='padding:10px;'>");
           //avatar
           if (user.getWantSeeAvatars() && author.getAvatarApproved() && author.getAvatar() != null && !author.getAvatar().trim().isEmpty() && author.getShowAvatar()){
              buffer.append("<a href='" + FJUrl.SETTINGS + "?id=9' rel='nofollow'><img border='0' src='" + author.getAvatar() + "?seed=" + (new Date()).getTime() + "'></a>");
           }else{
              buffer.append("<a href='" + FJUrl.SETTINGS + "?id=9' rel='nofollow'><img border='0' src='smiles/no_avatar.gif'></a>");
           }
           buffer.append("</div>");
           buffer.append("<span class='posthead'><u>" + locale.getString("mess111") + "</u></span><br>");
           //country
           if (!author.getShowCountry() || author.getCountry() == null || author.getCountry().isEmpty()){
              buffer.append("<span class='posthead'>" + locale.getString("mess114") + "</span><br>");
           }else{
              buffer.append("<span class='posthead'>" + HtmlChars.convertHtmlSymbols(author.getCountry()) + "</span><br>");
           }
           buffer.append("<span class='posthead'><u>" + locale.getString("mess112") + "</u></span><br>");
           if (!author.getShowCity() || author.getCity() == null || author.getCity().isEmpty()){
              buffer.append("<span class='posthead'>" + locale.getString("mess114") + "</span><br>");
           }else{
              buffer.append("<span class='posthead'>" + HtmlChars.convertHtmlSymbols(author.getCity()) + "</span><br>");
           }
           buffer.append("</td></tr></table>");
           buffer.append("</td><td valign='top' width='100%'>");
           buffer.append("<table width='100%'>");
           if (thread.isQuest() && post.getAnswers() != null){
              buffer.append(writeQuest(post, user, locale, thread, voiceService));
           }
           buffer.append("<tr><td>");
           buffer.append("<p class=post>" + fd_body(HtmlChars.convertHtmlSymbols(removeSlashes(post.getBody().getBody()))) + "</p>");
           buffer.append("</td></tr>");
           buffer.append("</table></td></tr>");
           buffer.append("<tr><td class='matras' colspan=2></td></tr>");
           buffer.append("<tr><td class='matras'></td><td>");
           buffer.append("<p class=post>" + fd_body(HtmlChars.convertHtmlSymbols(removeSlashes(author.getFooter()))) + "</p>");
           buffer.append("</td></tr>");
           buffer.append("<tr><td align='RIGHT' width='100%' colspan=2>");
           if (post.getHead().getNred()>0){
              Time postEditTime = new Time(post.getHead().getEditTime());
              buffer.append("<table class='matras' width='100%'>");
              buffer.append("<tr><td align='LEFT'>");
              buffer.append("<span class='posthead'>" + locale.getString("mess50") + "&nbsp;" + post.getHead().getNred() + "&nbsp;" + locale.getString("mess51") + "&nbsp;" + postEditTime.toString("dd.MM.yyyy HH:mm") + "</span>");
           }
           else {
              buffer.append("<table class='matras'>");
              buffer.append("<tr><td align='LEFT'>");
              buffer.append(" ");
           }
           buffer.append("</td>");
           if(user.isLogined()){
              //               if (this.isAdminForvard){
              //                  buffer.append("<td align='CENTER' width='70'>");
              //                  buffer.append("<span class='posthead'><a href='site.php?id=" + post.getThreadId() + "&post=" + this.id + "' rel=\"nofollow\">" + locale.getString("mess162") + "</a></span>");
              //                  buffer.append("</td>");
              //               }
              if (user.getId().equals(author.getId())) {
                 buffer.append("<td align='CENTER' width='70'>");
                 buffer.append("<span class='posthead'><a href='" + FJUrl.VIEW_THREAD + "?id=" + thread.getId() + "&reply=" + post.getId() + "#edit' rel=\"nofollow\">" + locale.getString("mess141") + "</a></span>");
                 buffer.append("</td>");
              }else{
                 buffer.append("<td align='CENTER' width='70'>");
                 buffer.append("<span class='posthead'><a href='" + FJUrl.VIEW_THREAD + "?id=" + thread.getId() + "&reply=" + post.getId() + "#edit' rel=\"nofollow\">" + locale.getString("mess139") + "</a></span>");
                 buffer.append("</td>");
                 buffer.append("<td align='CENTER' width='70'>");
                 buffer.append("<span class='posthead'><a href='" + FJUrl.VIEW_THREAD + "?id=" + thread.getId() + "&reply=" + post.getId() + "&ans=1#edit' rel=\"nofollow\">" + locale.getString("mess140") + "</a></span>");
                 buffer.append("</td>");
              }
           }
           buffer.append("</tr></table>");
           buffer.append("</td></tr>");
           buffer.append("</table>");
        }else{
           buffer.append( locale.getString("mess103"));
        }
        buffer.append("</div>");
        buffer.append("</td></tr>");
        return buffer;
     }

     private StringBuffer writeQuest(IFJPost post, IUser user, LocaleString locale, IFJThread thread, VoiceService voiceService) throws ConfigurationException, SQLException, InvalidKeyException, IOException{
        StringBuffer buffer = new StringBuffer(); 
        int nvcs = post.getVoicesAmount();
        buffer.append("<tr><td>");
        buffer.append("<p align=\"CENTER\"><font size=4><b>" + removeSlashes(post.getQuestion().getNode()) + "</b></font></p><br>");
        buffer.append("</td></tr>");
        buffer.append("<tr><td align=\"CENTER\">");
        List<IQuestNode> nodes = post.getAnswers();
        boolean userVoted = voiceService.isUserVoted(thread.getId(), user.getId());
        if (user.isLogined() && !userVoted && !thread.isClosed()){
           buffer.append("<form  action='" + FJUrl.VOICE + "' method='post'><table class=content>");
           for (int nodeIndex = 1; nodeIndex < nodes.size(); nodeIndex++) {
              IQuestNode questNode = nodes.get(nodeIndex);
              buffer.append("<tr><td class=voice_left align='right'>");
              String check = "";
              if (nodeIndex == 1){
                 check=" CHECKED";
              }
              if (questNode.getType() != 0){
                 buffer.append(locale.getString("mess143"));
                 if (questNode.getType() == 1){
                    buffer.append("<b>" + questNode.getUserNick() + "</b>");
                 }else{
                    buffer.append("<b>" + locale.getString("mess144") + "</b>");
                 }
                 buffer.append("</td><td class='voice_right' align='left'>");
                 buffer.append("<input type='radio' name='ANSWER' value='" + questNode.getId() + "'>&nbsp;" + fd_smiles(fd_href(removeSlashes(questNode.getNode())), false) + "<br>");
              }else {
                 buffer.append("</td><td class='voice_right' align='left'>");
                 buffer.append("<input type='radio' name='ANSWER' value='" + questNode.getId() + "'" + check + ">&nbsp;" + fd_smiles(fd_href(removeSlashes(questNode.getNode())), false) + "<br>");
              }
              buffer.append("</td></tr>");
           }
           buffer.append("<tr><td colspan='2' align='CENTER'>");
           buffer.append("<input type=hidden name=\"IDU1\" size=\"20\" value=\"" + user.getId() + "\">");
           buffer.append("<input type=hidden name=\"AUT1\" size=\"20\" value=\"" + user.getNick() + "\">");
           buffer.append("<input type=hidden name=\"IDT1\" size=\"20\" value=\"" + thread.getId() + "\">");
           if (user.getPass2() != null) {
              buffer.append("<input type=hidden name=\"PS21\" size=\"20\" value=\"" + user.getPass2() + "\">");
           }
           else {
              buffer.append("<input type=hidden name='PS11' size='20' value='" + user.getPass() + "'>");
           }
           buffer.append("<input type='submit' value='" + locale.getString("mess145") + "' name='OK'>");
           buffer.append("</td></tr>");
           buffer.append("</table></form>");
           buffer.append("</td></tr>");
           //Users can add custom answers 
           if (thread.getType() == ThreadType.QUEST2){
              boolean userVotes = false;
              for (int nodeIndex = 1; nodeIndex < nodes.size(); nodeIndex++) {
                 IQuestNode questNode = nodes.get(nodeIndex);
                 if (questNode.getUserId().equals(user.getId())) userVotes = true;
              }
              if (!userVotes){
                 buffer.append("<tr><td>");
                 buffer.append("<form  action='" + FJUrl.ADD_VOTE + "' method='post'><table align='center'>");
                 buffer.append("<tr><td>");
                 buffer.append(locale.getString("mess153") + ":<br>");
                 buffer.append("<input type='text' name='P' size='100'>");
                 buffer.append("<input type=hidden name='IDU2' size='20' value='" + user.getId() + "'>");
                 buffer.append("<input type=hidden name='AUT2' size='20' value='" + user.getNick() + "'>");
                 buffer.append("<input type=hidden name='IDT2' size='20' value='" + thread.getId() + "'>");
                 if (user.getPass2() != null) {
                    buffer.append("<input type=hidden name='PS22' size='20' value='" + user.getPass2() + "'>");
                 }
                 else {
                    buffer.append("<input type=hidden name='PS12' size='20' value='" + user.getPass() + "'>");
                 }
                 buffer.append("</td></tr>");
                 buffer.append("<tr><td align='center'>");
                 buffer.append("<input type='checkbox' name='HD' value='1' checked>&nbsp;" + locale.getString("mess146") + "<br>");
                 buffer.append("<input type='submit' value='" + locale.getString("mess145") + "' name='OK'>");
                 buffer.append("</td></tr>");
                 buffer.append("</table></form>");
                 buffer.append("</td></tr>");
              }
           }
        }
        buffer.append("<tr><td align='CENTER'>");
        buffer.append("<b>" + locale.getString("mess152") + ": " + nvcs + "</b>");
        buffer.append("</td></tr>");
        buffer.append("<tr><td align='CENTER'>");
        buffer.append("<table align='CENTER' class=control>");
        buffer.append("<tr class=heads><th class='internal'>");
        buffer.append(locale.getString("mess147"));
        buffer.append("</th><th class='internal'>");
        buffer.append(locale.getString("mess148"));
        buffer.append("</th><th class='internal'>");
        buffer.append(locale.getString("mess149"));
        buffer.append("</th><th class='internal' width='350'>");
        buffer.append(locale.getString("mess150"));
        buffer.append("</th><th class='internal'>");
        buffer.append(locale.getString("mess151"));
        buffer.append("</th></tr><tr>");
        for (int nodeIndex = 1; nodeIndex < nodes.size(); nodeIndex++) {
           IQuestNode questNode = nodes.get(nodeIndex);
           if (questNode.getType() == 0){
              buffer.append("<td align='LEFT' class='internal'></td>");
           }else if (questNode.getType() == 1){
              buffer.append("<td align='LEFT' class='internal'>" + questNode.getUserNick() + "</td>");
           }else if (questNode.getType() == 2){
              buffer.append("<td align='LEFT' class='internal'>" + locale.getString("mess144") + "</td>");
           }
           buffer.append("<td class='internal'>" + fd_body(questNode.getNode()) + "</td>");

           buffer.append("<td align='CENTER' class='internal'>");
           buffer.append(questNode.getGol() + "</td>");
           buffer.append("<td class='internal'><TABLE cellSpacing=0 cellPadding=0 width='" + Math.floor((questNode.getGol().doubleValue()/(nvcs == 0 ? 1 : nvcs))*300) + "' border=0><TR><TD align=left bgColor=red><FONT size=-3>&nbsp;</FONT></TD></TR></TABLE>");
           buffer.append("</td>");
           buffer.append("<td class='internal'>");
           buffer.append(Math.floor((questNode.getGol().doubleValue()/(nvcs == 0 ? 1 : nvcs))*1000)/10 + "%");
           buffer.append("</td></tr>");

        }
        buffer.append("</table>");
        if (user.isLogined() && userVoted && !thread.isClosed()){
           buffer.append("<form method='post' action='" + FJUrl.DELETE_VOICE + "' align='center'>");
           buffer.append("<input type=hidden name='IDT' size='20' value='" + thread.getId() + "'>");
           buffer.append(fd_form_add(user));
           buffer.append("<input type='submit' value='" + locale.getString("mess161") + "'>");
           buffer.append("</form>");
        }
        buffer.append("</div>");
        return buffer;
     }

     private boolean isIgnored(Long userId, List<IIgnor> ignorList){
        for(int arrIndex=0; arrIndex < ignorList.size(); arrIndex++) {
           if(ignorList.get(arrIndex).getUser().getId().equals(userId)) {
              return true;
           }
        }
        return false;
     }
}
